home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / tiff / tools / tiffdump.c < prev    next >
C/C++ Source or Header  |  1992-03-23  |  17KB  |  672 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/tools/RCS/tiffdump.c,v 1.22 92/03/24 14:11:26 sam Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler
  7.  * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and 
  10.  * its documentation for any purpose is hereby granted without fee, provided
  11.  * that (i) the above copyright notices and this permission notice appear in
  12.  * all copies of the software and related documentation, and (ii) the names of
  13.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  14.  * publicity relating to the software without the specific, prior written
  15.  * permission of Sam Leffler and Silicon Graphics.
  16.  * 
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  18.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  19.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  20.  * 
  21.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  22.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  23.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  25.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  26.  * OF THIS SOFTWARE.
  27.  */
  28.  
  29. #include <stdio.h>
  30. #if defined(VMS)
  31. #include <unixio.h>
  32. #include <file.h>
  33. #else
  34. #include <fcntl.h>
  35. #endif
  36. #if defined(MSDOS)
  37. #include <malloc.h>
  38. #else
  39. #define    O_BINARY    0
  40. #endif
  41. #include "tiff.h"
  42.  
  43. #if defined(SYSV) || defined(THINK_C) || defined(applec) || defined(VMS)
  44. #define    bcopy(src,dst,len)    memcpy(dst, src, len)
  45. #endif
  46.  
  47. char    *curfile;
  48. int    swabflag;
  49. int    bigendian;
  50. int    typeshift[13];    /* data type shift counts */
  51. long    typemask[13];    /* data type masks */
  52. long    ReadDirectory();
  53.  
  54. main(argc, argv)
  55.     char *argv[];
  56. {
  57.     int one = 1, fd;
  58.     int multiplefiles = (argc > 1);
  59.  
  60.     bigendian = (*(char *)&one == 0);
  61.     for (argc--, argv++; argc > 0; argc--, argv++) {
  62.         fd = open(argv[0], O_RDONLY|O_BINARY, 0);
  63.         if (fd < 0) {
  64.             perror(argv[0]);
  65.             exit(-1);
  66.         }
  67.         if (multiplefiles)
  68.             printf("%s:\n", argv[0]);
  69.         curfile = *argv;
  70.         swabflag = 0;
  71.         dump(fd);
  72.         close(fd);
  73.     }
  74.     exit(0);
  75. }
  76.  
  77. TIFFHeader h;
  78.  
  79. #define    ord(e)    ((int)e)
  80.  
  81. /*
  82.  * Initialize shift & mask tables and byte
  83.  * swapping state according to the file
  84.  * byte order.
  85.  */
  86. static
  87. InitByteOrder(magic)
  88.     int magic;
  89. {
  90.     typemask[0] = 0;
  91.     typemask[ord(TIFF_BYTE)] = 0xff;
  92.     typemask[ord(TIFF_SBYTE)] = 0xff;
  93.     typemask[ord(TIFF_UNDEFINED)] = 0xff;
  94.     typemask[ord(TIFF_SHORT)] = 0xffff;
  95.     typemask[ord(TIFF_SSHORT)] = 0xffff;
  96.     typemask[ord(TIFF_LONG)] = 0xffffffff;
  97.     typemask[ord(TIFF_SLONG)] = 0xffffffff;
  98.     typemask[ord(TIFF_RATIONAL)] = 0xffffffff;
  99.     typemask[ord(TIFF_SRATIONAL)] = 0xffffffff;
  100.     typemask[ord(TIFF_FLOAT)] = 0xffffffff;
  101.     typemask[ord(TIFF_DOUBLE)] = 0xffffffff;
  102.     typeshift[0] = 0;
  103.     typeshift[ord(TIFF_LONG)] = 0;
  104.     typeshift[ord(TIFF_SLONG)] = 0;
  105.     typeshift[ord(TIFF_RATIONAL)] = 0;
  106.     typeshift[ord(TIFF_SRATIONAL)] = 0;
  107.     typeshift[ord(TIFF_FLOAT)] = 0;
  108.     typeshift[ord(TIFF_DOUBLE)] = 0;
  109.     if (magic == TIFF_BIGENDIAN) {
  110.         typeshift[ord(TIFF_BYTE)] = 24;
  111.         typeshift[ord(TIFF_SBYTE)] = 24;
  112.         typeshift[ord(TIFF_SHORT)] = 16;
  113.         typeshift[ord(TIFF_SSHORT)] = 16;
  114.         swabflag = !bigendian;
  115.     } else {
  116.         typeshift[ord(TIFF_BYTE)] = 0;
  117.         typeshift[ord(TIFF_SBYTE)] = 0;
  118.         typeshift[ord(TIFF_SHORT)] = 0;
  119.         typeshift[ord(TIFF_SSHORT)] = 0;
  120.         swabflag = bigendian;
  121.     }
  122. }
  123.  
  124. dump(fd)
  125.     int fd;
  126. {
  127.     long off;
  128.     int i;
  129.  
  130.     lseek(fd, 0L, 0);
  131.     if (read(fd, &h, sizeof (h)) != sizeof (h))
  132.         ReadError("TIFF header");
  133.     /*
  134.      * Setup the byte order handling.
  135.      */
  136.     if (h.tiff_magic != TIFF_BIGENDIAN && h.tiff_magic != TIFF_LITTLEENDIAN)
  137.         Fatal("Not a TIFF file, bad magic number %u (0x%x)",
  138.             h.tiff_magic, h.tiff_magic);
  139.     InitByteOrder(h.tiff_magic);
  140.     /*
  141.      * Swap header if required.
  142.      */
  143.     if (swabflag) {
  144.         TIFFSwabShort(&h.tiff_version);
  145.         TIFFSwabLong(&h.tiff_diroff);
  146.     }
  147.     /*
  148.      * Now check version (if needed, it's been byte-swapped).
  149.      * Note that this isn't actually a version number, it's a
  150.      * magic number that doesn't change (stupid).
  151.      */
  152.     if (h.tiff_version != TIFF_VERSION)
  153.         Fatal("Not a TIFF file, bad version number %u (0x%x)",
  154.             h.tiff_version, h.tiff_version); 
  155.     printf("Magic: 0x%x <%s-endian> Version: 0x%x\n",
  156.         h.tiff_magic,
  157.         h.tiff_magic == TIFF_BIGENDIAN ? "big" : "little",
  158.         h.tiff_version);
  159.     i = 0;
  160.     off = h.tiff_diroff;
  161.     while (off) {
  162.         if (i > 0)
  163.             putchar('\n');
  164.         printf("Directory %d: offset %lu (0x%lx)\n", i++, off, off);
  165.         off = ReadDirectory(fd, off);
  166.     }
  167. }
  168.  
  169. static int datawidth[] = {
  170.     0,    /* nothing */
  171.     1,    /* TIFF_BYTE */
  172.     1,    /* TIFF_ASCII */
  173.     2,    /* TIFF_SHORT */
  174.     4,    /* TIFF_LONG */
  175.     8,    /* TIFF_RATIONAL */
  176.     1,    /* TIFF_SBYTE */
  177.     1,    /* TIFF_UNDEFINED */
  178.     2,    /* TIFF_SSHORT */
  179.     4,    /* TIFF_SLONG */
  180.     8,    /* TIFF_SRATIONAL */
  181.     4,    /* TIFF_FLOAT */
  182.     8,    /* TIFF_DOUBLE */
  183. };
  184. #define    NWIDTHS    (sizeof (datawidth) / sizeof (datawidth[0]))
  185. static    int TIFFFetchData();
  186.  
  187. /*
  188.  * Read the next TIFF directory from a file
  189.  * and convert it to the internal format.
  190.  * We read directories sequentially.
  191.  */
  192. long
  193. ReadDirectory(fd, off)
  194.     int fd;
  195.     long off;
  196. {
  197.     register TIFFDirEntry *dp;
  198.     register int n;
  199.     TIFFDirEntry *dir = 0;
  200.     unsigned short dircount;
  201.     char *cp;
  202.     int space;
  203.     long nextdiroff = 0;
  204.  
  205.     if (off == 0)            /* no more directories */
  206.         goto done;
  207.     if (lseek(fd, off, 0) != off) {
  208.         Fatal("Seek error accessing TIFF directory");
  209.         goto done;
  210.     }
  211.     if (read(fd, &dircount, sizeof (short)) != sizeof (short)) {
  212.         ReadError("directory count");
  213.         goto done;
  214.     }
  215.     if (swabflag)
  216.         TIFFSwabShort(&dircount);
  217.     dir = (TIFFDirEntry *)malloc(dircount * sizeof (TIFFDirEntry));
  218.     if (dir == NULL) {
  219.         Fatal("No space for TIFF directory");
  220.         goto done;
  221.     }
  222.     n = read(fd, dir, dircount*sizeof (*dp));
  223.     if (n != dircount*sizeof (*dp)) {
  224.         n /= sizeof (*dp);
  225.         Error(
  226.         "Could only read %u of %u entries in directory at offset 0x%x",
  227.             n, dircount, off);
  228.         dircount = n;
  229.     }
  230.     if (read(fd, &nextdiroff, sizeof (long)) != sizeof (long))
  231.         nextdiroff = 0;
  232.     if (swabflag)
  233.         TIFFSwabLong(&nextdiroff);
  234.     for (dp = dir, n = dircount; n > 0; n--, dp++) {
  235.         if (swabflag) {
  236.             TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
  237.             TIFFSwabArrayOfLong(&dp->tdir_count, 2);
  238.         }
  239.         PrintTag(stdout, dp->tdir_tag);
  240.         putchar(' ');
  241.         PrintType(stdout, dp->tdir_type);
  242.         putchar(' ');
  243.         printf("%u<", dp->tdir_count);
  244.         if (dp->tdir_type >= NWIDTHS) {
  245.             printf(">\n");
  246.             continue;
  247.         }
  248.         space = dp->tdir_count * datawidth[dp->tdir_type];
  249.         if (space <= 4) {
  250.             switch (dp->tdir_type) {
  251.             case TIFF_ASCII: {
  252.                 char data[4];
  253.                 bcopy(&dp->tdir_offset, data, 4);
  254.                 if (swabflag)
  255.                     TIFFSwabLong(data);
  256.                 PrintData(stdout,
  257.                     dp->tdir_type, dp->tdir_count, data);
  258.                 break;
  259.             }
  260.             case TIFF_BYTE:
  261.             case TIFF_SBYTE:
  262.                 if (h.tiff_magic == TIFF_LITTLEENDIAN) {
  263.                     switch ((int)dp->tdir_count) {
  264.                     case 4:
  265.                         printf("0x%02x",
  266.                             dp->tdir_offset&0xff);
  267.                     case 3:
  268.                         printf("0x%02x",
  269.                             (dp->tdir_offset>>8)&0xff);
  270.                     case 2:
  271.                         printf("0x%02x",
  272.                             (dp->tdir_offset>>16)&0xff);
  273.                     case 1:
  274.                         printf("0x%02x",
  275.                             dp->tdir_offset>>24);
  276.                         break;
  277.                     }
  278.                 } else {
  279.                     switch ((int)dp->tdir_count) {
  280.                     case 4:
  281.                         printf("0x%02x",
  282.                             dp->tdir_offset>>24);
  283.                     case 3:
  284.                         printf("0x%02x",
  285.                             (dp->tdir_offset>>16)&0xff);
  286.                     case 2:
  287.                         printf("0x%02x",
  288.                             (dp->tdir_offset>>8)&0xff);
  289.                     case 1:
  290.                         printf("0x%02x",
  291.                             dp->tdir_offset&0xff);
  292.                         break;
  293.                     }
  294.                 }
  295.                 break;
  296.             case TIFF_SHORT:
  297.             case TIFF_SSHORT:
  298.                 if (h.tiff_magic == TIFF_LITTLEENDIAN) {
  299.                     switch (dp->tdir_count) {
  300.                     case 2:
  301.                         printf("%u ",
  302.                             dp->tdir_offset&0xffff);
  303.                     case 1:
  304.                         printf("%u",
  305.                             dp->tdir_offset>>16);
  306.                         break;
  307.                     }
  308.                 } else {
  309.                     switch (dp->tdir_count) {
  310.                     case 2:
  311.                         printf("%u ",
  312.                             dp->tdir_offset>>16);
  313.                     case 1:
  314.                         printf("%u",
  315.                             dp->tdir_offset&0xffff);
  316.                         break;
  317.                     }
  318.                 }
  319.                 break;
  320.             case TIFF_LONG:
  321.                 printf("%lu", dp->tdir_offset);
  322.                 break;
  323.             case TIFF_SLONG:
  324.                 printf("%ld", dp->tdir_offset);
  325.                 break;
  326.             }
  327.         } else {
  328.             char *data = (char *)malloc(space);
  329.             if (data) {
  330.                 if (TIFFFetchData(fd, dp, data))
  331.                     PrintData(stdout, dp->tdir_type,
  332.                         dp->tdir_count, data);
  333.                 free(data);
  334.             } else
  335.                 Error("No space for data for tag %u",
  336.                     dp->tdir_tag);
  337.         }
  338.         printf(">\n");
  339.     }
  340. done:
  341.     if (dir)
  342.         free((char *)dir);
  343.     return (nextdiroff);
  344. }
  345.  
  346. static    struct tagname {
  347.     int    tag;
  348.     char    *name;
  349. } tagnames[] = {
  350.     { TIFFTAG_SUBFILETYPE,    "SubFileType" },
  351.     { TIFFTAG_OSUBFILETYPE,    "OldSubFileType" },
  352.     { TIFFTAG_IMAGEWIDTH,    "ImageWidth" },
  353.     { TIFFTAG_IMAGELENGTH,    "ImageLength" },
  354.     { TIFFTAG_BITSPERSAMPLE,    "BitsPerSample" },
  355.     { TIFFTAG_COMPRESSION,    "Compression" },
  356.     { TIFFTAG_PHOTOMETRIC,    "Photometric" },
  357.     { TIFFTAG_THRESHHOLDING,    "Threshholding" },
  358.     { TIFFTAG_CELLWIDTH,    "CellWidth" },
  359.     { TIFFTAG_CELLLENGTH,    "CellLength" },
  360.     { TIFFTAG_FILLORDER,    "FillOrder" },
  361.     { TIFFTAG_DOCUMENTNAME,    "DocumentName" },
  362.     { TIFFTAG_IMAGEDESCRIPTION,    "ImageDescription" },
  363.     { TIFFTAG_MAKE,        "Make" },
  364.     { TIFFTAG_MODEL,        "Model" },
  365.     { TIFFTAG_STRIPOFFSETS,    "StripOffsets" },
  366.     { TIFFTAG_ORIENTATION,    "Orientation" },
  367.     { TIFFTAG_SAMPLESPERPIXEL,    "SamplesPerPixel" },
  368.     { TIFFTAG_ROWSPERSTRIP,    "RowsPerStrip" },
  369.     { TIFFTAG_STRIPBYTECOUNTS,    "StripByteCounts" },
  370.     { TIFFTAG_MINSAMPLEVALUE,    "MinSampleValue" },
  371.     { TIFFTAG_MAXSAMPLEVALUE,    "MaxSampleValue" },
  372.     { TIFFTAG_XRESOLUTION,    "XResolution" },
  373.     { TIFFTAG_YRESOLUTION,    "YResolution" },
  374.     { TIFFTAG_PLANARCONFIG,    "PlanarConfig" },
  375.     { TIFFTAG_PAGENAME,        "PageName" },
  376.     { TIFFTAG_XPOSITION,    "XPosition" },
  377.     { TIFFTAG_YPOSITION,    "YPosition" },
  378.     { TIFFTAG_FREEOFFSETS,    "FreeOffsets" },
  379.     { TIFFTAG_FREEBYTECOUNTS,    "FreeByteCounts" },
  380.     { TIFFTAG_GRAYRESPONSEUNIT,    "GrayResponseUnit" },
  381.     { TIFFTAG_GRAYRESPONSECURVE,"GrayResponseCurve" },
  382.     { TIFFTAG_GROUP3OPTIONS,    "Group3Options" },
  383.     { TIFFTAG_GROUP4OPTIONS,    "Group4Options" },
  384.     { TIFFTAG_RESOLUTIONUNIT,    "ResolutionUnit" },
  385.     { TIFFTAG_PAGENUMBER,    "PageNumber" },
  386.     { TIFFTAG_COLORRESPONSEUNIT,"ColorResponseUnit" },
  387.     { TIFFTAG_TRANSFERFUNCTION,    "TransferFunction" },
  388.     { TIFFTAG_SOFTWARE,        "Software" },
  389.     { TIFFTAG_DATETIME,        "DateTime" },
  390.     { TIFFTAG_ARTIST,        "Artist" },
  391.     { TIFFTAG_HOSTCOMPUTER,    "HostComputer" },
  392.     { TIFFTAG_PREDICTOR,    "Predictor" },
  393.     { TIFFTAG_WHITEPOINT,    "Whitepoint" },
  394.     { TIFFTAG_PRIMARYCHROMATICITIES,"PrimaryChromaticities" },
  395.     { TIFFTAG_COLORMAP,        "Colormap" },
  396.     { TIFFTAG_HALFTONEHINTS,    "HalftoneHints" },
  397.     { TIFFTAG_TILEWIDTH,    "TileWidth" },
  398.     { TIFFTAG_TILELENGTH,    "TileLength" },
  399.     { TIFFTAG_TILEOFFSETS,    "TileOffsets" },
  400.     { TIFFTAG_TILEBYTECOUNTS,    "TileByteCounts" },
  401.     { TIFFTAG_BADFAXLINES,    "BadFaxLines" },
  402.     { TIFFTAG_CLEANFAXDATA,    "CleanFaxData" },
  403.     { TIFFTAG_CONSECUTIVEBADFAXLINES, "ConsecutiveBadFaxLines" },
  404.     { TIFFTAG_INKSET,        "InkSet" },
  405.     { TIFFTAG_INKNAMES,        "InkNames" },
  406.     { TIFFTAG_DOTRANGE,        "DotRange" },
  407.     { TIFFTAG_TARGETPRINTER,    "TargetPrinter" },
  408.     { TIFFTAG_EXTRASAMPLES,    "ExtraSamples" },
  409.     { TIFFTAG_SAMPLEFORMAT,    "SampleFormat" },
  410.     { TIFFTAG_SMINSAMPLEVALUE,    "SMinSampleValue" },
  411.     { TIFFTAG_SMAXSAMPLEVALUE,    "SMaxSampleValue" },
  412.     { TIFFTAG_JPEGPROC,        "JPEGProcessingMode" },
  413.     { TIFFTAG_JPEGIFOFFSET,    "JPEGInterchangeFormat" },
  414.     { TIFFTAG_JPEGIFBYTECOUNT,    "JPEGInterchangeFormatLength" },
  415.     { TIFFTAG_JPEGRESTARTINTERVAL,"JPEGRestartInterval" },
  416.     { TIFFTAG_JPEGLOSSLESSPREDICTORS,"JPEGLosslessPredictors" },
  417.     { TIFFTAG_JPEGPOINTTRANSFORM,"JPEGPointTransform" },
  418.     { TIFFTAG_JPEGQTABLES,    "JPEGQTables" },
  419.     { TIFFTAG_JPEGDCTABLES,    "JPEGDCTables" },
  420.     { TIFFTAG_JPEGACTABLES,    "JPEGACTables" },
  421.     { TIFFTAG_YCBCRCOEFFICIENTS,"YCbCrCoefficients" },
  422.     { TIFFTAG_YCBCRSUBSAMPLING,    "YCbCrSubsampling" },
  423.     { TIFFTAG_YCBCRPOSITIONING,    "YCbCrPositioning" },
  424.     { TIFFTAG_REFERENCEBLACKWHITE, "ReferenceBlackWhite" },
  425.     { TIFFTAG_MATTEING,        "OBSOLETE Matteing" },
  426.     { TIFFTAG_DATATYPE,        "OBSOLETE DataType" },
  427.     { TIFFTAG_IMAGEDEPTH,    "ImageDepth" },
  428.     { TIFFTAG_TILEDEPTH,    "TileDepth" },
  429.     { 32768,            "OLD BOGUS Matteing tag" },
  430. };
  431. #define    NTAGS    (sizeof (tagnames) / sizeof (tagnames[0]))
  432.  
  433. PrintTag(fd, tag)
  434.     FILE *fd;
  435.     unsigned short tag;
  436. {
  437.     register struct tagname *tp;
  438.  
  439.     for (tp = tagnames; tp < &tagnames[NTAGS]; tp++)
  440.         if (tp->tag == tag) {
  441.             fprintf(fd, "%s (%u)", tp->name, tag);
  442.             return;
  443.         }
  444.     fprintf(fd, "%u (0x%x)", tag, tag);
  445. }
  446.  
  447. PrintType(fd, type)
  448.     FILE *fd;
  449.     unsigned short type;
  450. {
  451.     static char *typenames[] = {
  452.         "0",
  453.         "BYTE",
  454.         "ASCII",
  455.         "SHORT",
  456.         "LONG",
  457.         "RATIONAL",
  458.         "SBYTE",
  459.         "UNDEFINED",
  460.         "SSHORT",
  461.         "SLONG",
  462.         "SRATIONAL",
  463.         "FLOAT",
  464.         "DOUBLE"
  465.     };
  466. #define    NTYPES    (sizeof (typenames) / sizeof (typenames[0]))
  467.  
  468.     if (type < NTYPES)
  469.         fprintf(fd, "%s (%u)", typenames[type], type);
  470.     else
  471.         fprintf(fd, "%u (0x%x)", type, type);
  472. }
  473. #undef    NTYPES
  474.  
  475. PrintData(fd, type, count, data)
  476.     FILE *fd;
  477.     unsigned short type;
  478.     long count;
  479.     unsigned char *data;
  480. {
  481.  
  482.     switch (type) {
  483.     case TIFF_BYTE:
  484.         while (count-- > 0)
  485.             fprintf(fd, "%u%s", *data++, count > 0 ? " " : "");
  486.         break;
  487.     case TIFF_SBYTE:
  488.         while (count-- > 0)
  489.             fprintf(fd, "%d%s", *(char *)data++, count > 0 ? " " : "");
  490.         break;
  491.     case TIFF_UNDEFINED:
  492.         while (count-- > 0)
  493.             fprintf(fd, "0x%02x", *data++);
  494.         break;
  495.     case TIFF_ASCII:
  496.         fprintf(fd, "%.*s", count, data);
  497.         break;
  498.     case TIFF_SHORT: {
  499.         register unsigned short *wp = (unsigned short *)data;
  500.         while (count-- > 0)
  501.             fprintf(fd, "%u%s", *wp++, count > 0 ? " " : "");
  502.         break;
  503.     }
  504.     case TIFF_SSHORT: {
  505.         register short *wp = (short *)data;
  506.         while (count-- > 0)
  507.             fprintf(fd, "%d%s", *wp++, count > 0 ? " " : "");
  508.         break;
  509.     }
  510.     case TIFF_LONG: {
  511.         register unsigned long *lp = (unsigned long *)data;
  512.         while (count-- > 0)
  513.             fprintf(fd, "%lu%s", *lp++, count > 0 ? " " : "");
  514.         break;
  515.     }
  516.     case TIFF_SLONG: {
  517.         register long *lp = (long *)data;
  518.         while (count-- > 0)
  519.             fprintf(fd, "%ld%s", *lp++, count > 0 ? " " : "");
  520.         break;
  521.     }
  522.     case TIFF_RATIONAL: {
  523.         register unsigned long *lp = (unsigned long *)data;
  524.         while (count-- > 0) {
  525.             if (lp[1] == 0)
  526.                 fprintf(fd, "Nan (%lu/%lu)", lp[0], lp[1]);
  527.             else
  528.                 fprintf(fd, "%g",
  529.                     (double)lp[0] / (double)lp[1]);
  530.             if (count > 0)
  531.                 fprintf(fd, " ");
  532.             lp += 2;
  533.         }
  534.         break;
  535.     }
  536.     case TIFF_SRATIONAL: {
  537.         register long *lp = (long *)data;
  538.         while (count-- > 0) {
  539.             if (lp[1] == 0)
  540.                 fprintf(fd, "Nan (%ld/%ld)", lp[0], lp[1]);
  541.             else
  542.                 fprintf(fd, "%g",
  543.                     (double)lp[0] / (double)lp[1]);
  544.             if (count > 0)
  545.                 fprintf(fd, " ");
  546.             lp += 2;
  547.         }
  548.         break;
  549.     }
  550.     case TIFF_FLOAT: {
  551.         register float *fp = (float *)data;
  552.         while (count-- > 0)
  553.             fprintf(fd, "%g%s", *fp++, count > 0 ? " " : "");
  554.         break;
  555.     }
  556.     case TIFF_DOUBLE: {
  557.         register double *dp = (double *)data;
  558.         while (count-- > 0)
  559.             fprintf(fd, "%g%s", *dp++, count > 0 ? " " : "");
  560.         break;
  561.     }
  562.     }
  563. }
  564.  
  565. TIFFSwabShort(wp)
  566.     unsigned short *wp;
  567. {
  568.     register unsigned char *cp = (unsigned char *)wp;
  569.     int t;
  570.  
  571.     t = cp[1]; cp[1] = cp[0]; cp[0] = t;
  572. }
  573.  
  574. TIFFSwabLong(lp)
  575.     unsigned long *lp;
  576. {
  577.     register unsigned char *cp = (unsigned char *)lp;
  578.     int t;
  579.  
  580.     t = cp[3]; cp[3] = cp[0]; cp[0] = t;
  581.     t = cp[2]; cp[2] = cp[1]; cp[1] = t;
  582. }
  583.  
  584. TIFFSwabArrayOfShort(wp, n)
  585.     unsigned short *wp;
  586.     register int n;
  587. {
  588.     register unsigned char *cp;
  589.     register int t;
  590.  
  591.     /* XXX unroll loop some */
  592.     while (n-- > 0) {
  593.         cp = (unsigned char *)wp;
  594.         t = cp[1]; cp[1] = cp[0]; cp[0] = t;
  595.         wp++;
  596.     }
  597. }
  598.  
  599. TIFFSwabArrayOfLong(lp, n)
  600.     register unsigned long *lp;
  601.     register int n;
  602. {
  603.     register unsigned char *cp;
  604.     register int t;
  605.  
  606.     /* XXX unroll loop some */
  607.     while (n-- > 0) {
  608.         cp = (unsigned char *)lp;
  609.         t = cp[3]; cp[3] = cp[0]; cp[0] = t;
  610.         t = cp[2]; cp[2] = cp[1]; cp[1] = t;
  611.         lp++;
  612.     }
  613. }
  614.  
  615. /*
  616.  * Fetch a contiguous directory item.
  617.  */
  618. static
  619. TIFFFetchData(fd, dir, cp)
  620.     int fd;
  621.     TIFFDirEntry *dir;
  622.     char *cp;
  623. {
  624.     int cc, w;
  625.  
  626.     w = (dir->tdir_type < NWIDTHS ? datawidth[dir->tdir_type] : 0);
  627.     cc = dir->tdir_count * w;
  628.     if (lseek(fd, dir->tdir_offset, 0) == dir->tdir_offset &&
  629.         read(fd, cp, cc) == cc) {
  630.         if (swabflag) {
  631.             switch (dir->tdir_type) {
  632.             case TIFF_SHORT:
  633.             case TIFF_SSHORT:
  634.                 TIFFSwabArrayOfShort(cp, dir->tdir_count);
  635.                 break;
  636.             case TIFF_LONG:
  637.             case TIFF_SLONG:
  638.                 TIFFSwabArrayOfLong(cp, dir->tdir_count);
  639.                 break;
  640.             case TIFF_RATIONAL:
  641.             case TIFF_DOUBLE:
  642.                 TIFFSwabArrayOfLong(cp, 2*dir->tdir_count);
  643.                 break;
  644.             }
  645.         }
  646.         return (cc);
  647.     }
  648.     Error("Error while reading data for tag %u", dir->tdir_tag);
  649.     return (0);
  650. }
  651.  
  652. ReadError(what)
  653.     char *what;
  654. {
  655.     Fatal("Error while reading %s", what);
  656. }
  657.  
  658. Error(fmt, a1, a2, a3, a4, a5)
  659.     char *fmt;
  660. {
  661.     fprintf(stderr, "%s: ", curfile);
  662.     fprintf(stderr, fmt, a1, a2, a3, a4, a5);
  663.     fprintf(stderr, ".\n");
  664. }
  665.  
  666. Fatal(fmt, a1, a2, a3, a4, a5)
  667.     char *fmt;
  668. {
  669.     Error(fmt, a1, a2, a3, a4, a5);
  670.     exit(-1);
  671. }
  672.